import React, { FunctionComponent } from 'react';
import { graphql, PreloadedQuery, useFragment, usePreloadedQuery } from 'react-relay';
import List from '@mui/material/List';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import ListItem from '@mui/material/ListItem';
import makeStyles from '@mui/styles/makeStyles';
import { Link } from 'react-router-dom';
import Chip from '@mui/material/Chip';
import Typography from '@mui/material/Typography';
import { KeyboardArrowRightOutlined } from '@mui/icons-material';
import type { Theme } from '../../../../components/Theme';
import useQueryLoading from '../../../../utils/hooks/useQueryLoading';
import {
  MalwareAnalysesOrdering,
  StixCyberObservableMalwareAnalysesQuery,
  StixCyberObservableMalwareAnalysesQuery$variables,
} from './__generated__/StixCyberObservableMalwareAnalysesQuery.graphql';
import ItemIcon from '../../../../components/ItemIcon';
import FieldOrEmpty from '../../../../components/FieldOrEmpty';
import { useFormatter } from '../../../../components/i18n';
import { StixCyberObservableMalwareAnalyses_data$key } from './__generated__/StixCyberObservableMalwareAnalyses_data.graphql';
import StixCyberObservableMalwareAnalysesDummyList from './StixCyberObservableMalwareAnalysesDummyList';

// Deprecated - https://mui.com/system/styles/basics/
// Do not use it for new code.
const useStyles = makeStyles<Theme>((theme) => ({
  goIcon: {
    position: 'absolute',
    right: -10,
  },
  bodyItem: {
    float: 'left',
    height: 20,
    whiteSpace: 'nowrap',
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    marginRight: 10,
  },
  item: {
    minHeight: 50,
    maxHeight: 50,
    paddingRight: 0,
  },
  itemIcon: {
    marginRight: 0,
    color: theme.palette.primary.main,
  },
  chip: {
    fontSize: 12,
    height: 20,
    float: 'left',
    marginRight: 7,
    textTransform: 'uppercase',
    borderRadius: 4,
  },
  withoutMalwareAnalysesTable: {
    display: 'table',
    height: '100%',
    width: '100%',
    paddingTop: 15,
    paddingBottom: 15,
  },
  withoutMalwareAnalysesTableCell: {
    display: 'table-cell',
    verticalAlign: 'middle',
    textAlign: 'center',
  },
}));

const query = graphql`
  query StixCyberObservableMalwareAnalysesQuery(
    $filters: FilterGroup
    $orderBy: MalwareAnalysesOrdering
    $orderMode: OrderingMode
  ) {
    malwareAnalyses(
      filters: $filters
      orderBy: $orderBy
      orderMode: $orderMode
    ) {
      edges {
        node {
          ...StixCyberObservableMalwareAnalyses_data
        }
      }
    }
  }
`;

const fragment = graphql`
  fragment StixCyberObservableMalwareAnalyses_data on MalwareAnalysis {
    id
    result_name
    submitted
    entity_type
    createdBy {
      ... on Identity {
        name
      }
    }
    result
  }
`;

interface StixCyberObservableMalwareAnalysesListLineProps {
  malwareAnalysisNode: StixCyberObservableMalwareAnalyses_data$key;
}

const StixCyberObservableMalwareAnalysesListLine: FunctionComponent<
StixCyberObservableMalwareAnalysesListLineProps
> = ({ malwareAnalysisNode }) => {
  const classes = useStyles();
  const malwareAnalysis = useFragment(fragment, malwareAnalysisNode);
  const { fd } = useFormatter();
  return (
    <ListItem
      key={malwareAnalysis.id}
      classes={{ root: classes.item }}
      divider
      button
      component={Link}
      to={`/dashboard/analyses/malware_analyses/${malwareAnalysis.id}`}
    >
      <ListItemIcon classes={{ root: classes.itemIcon }}>
        <ItemIcon type={malwareAnalysis.entity_type} />
      </ListItemIcon>
      <ListItemText
        primary={
          <div>
            <div className={classes.bodyItem} style={{ width: '30%' }}>
              {malwareAnalysis.result_name}
            </div>
            <div className={classes.bodyItem} style={{ width: '20%' }}>
              {malwareAnalysis.createdBy?.name}
            </div>
            <div className={classes.bodyItem} style={{ width: '15%' }}>
              {fd(malwareAnalysis.submitted)}
            </div>
            <div className={classes.bodyItem} style={{ width: '20%' }}>
              <FieldOrEmpty source={malwareAnalysis.result}>
                <Chip
                  key={malwareAnalysis.result}
                  classes={{ root: classes.chip }}
                  label={malwareAnalysis.result}
                />
              </FieldOrEmpty>
            </div>
          </div>
        }
      />
      <ListItemIcon classes={{ root: classes.goIcon }}>
        <KeyboardArrowRightOutlined />
      </ListItemIcon>
    </ListItem>
  );
};

interface StixCyberObservableMalwareAnalysesListProps {
  queryRef: PreloadedQuery<StixCyberObservableMalwareAnalysesQuery>;
}

const StixCyberObservableMalwareAnalysesList: FunctionComponent<
StixCyberObservableMalwareAnalysesListProps
> = ({ queryRef }) => {
  const { t_i18n } = useFormatter();
  const classes = useStyles();
  const { malwareAnalyses } = usePreloadedQuery<StixCyberObservableMalwareAnalysesQuery>(query, queryRef);
  const hasMalwareAnalyses: boolean = (malwareAnalyses?.edges ?? []).length !== 0;
  return (
    <>
      {hasMalwareAnalyses ? (
        malwareAnalyses?.edges?.map((malwareAnalysisEdge, index) => (
          <StixCyberObservableMalwareAnalysesListLine
            key={index}
            malwareAnalysisNode={malwareAnalysisEdge.node}
          />
        ))
      ) : (
        <div className={classes.withoutMalwareAnalysesTable}>
          <span className={classes.withoutMalwareAnalysesTableCell}>
            {t_i18n('No malware analysis on this observable.')}
          </span>
        </div>
      )}
    </>
  );
};

interface StixCyberObservableMalwareAnalysesComponentProps {
  observableId: string;
}

const StixCyberObservableMalwareAnalyses: FunctionComponent<
StixCyberObservableMalwareAnalysesComponentProps
> = ({ observableId }) => {
  const { t_i18n } = useFormatter();
  const options: StixCyberObservableMalwareAnalysesQuery$variables = {
    orderBy: 'submitted' as MalwareAnalysesOrdering,
    orderMode: 'desc',
    filters: {
      mode: 'and',
      filterGroups: [],
      filters: [
        {
          key: ['analysisSample'],
          values: [observableId],
          operator: 'eq',
          mode: 'or',
        },
      ],
    },
  };
  const queryRef = useQueryLoading<StixCyberObservableMalwareAnalysesQuery>(
    query,
    options,
  );
  return (
    <div style={{ marginTop: 13 }}>
      <Typography variant="h3" gutterBottom={true}>
        {t_i18n('Malware analyses')}
      </Typography>
      <List style={{ marginTop: 5 }}>
        {queryRef && (
          <React.Suspense
            fallback={<StixCyberObservableMalwareAnalysesDummyList />}
          >
            <StixCyberObservableMalwareAnalysesList queryRef={queryRef} />
          </React.Suspense>
        )}
      </List>
    </div>
  );
};

export default StixCyberObservableMalwareAnalyses;
